/***************************************************************************************
 * SAGE - Scalable Adaptive Graphics Environment
 *
 * Module:  sageCircBuf.h
 * Author : Byungil Jeong
 *
 *	Description: This is the header file for the circular buffer of sage pixel blocks
 *
 *	Notes	:	This class is supposed to provide the common buffers for holding 
 *			the pixel blocks. It also takes care of the reading and writing of pixel blocks 
 *			in a circular fashion. The member functions will be able to provide a complete 
 *			interface to handling these buffers. 
 *			
 *			The algo is that the buffers are writen to and read from in the same direction 
 *			[0 to n and then back to 0]
 *			
 *			
 * Copyright (C) 2004 Electronic Visualization Laboratory,
 * University of Illinois at Chicago
 *
 * This library is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation; either Version 2.1 of the License, or
 * (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
 * License for more details.
 *
 * You should have received a copy of the GNU Lesser Public License along
 * with this library; if not, write to the Free Software Foundation, Inc.,
 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 *
 * Direct questions, comments etc about SAGE to bijeong@evl.uic.edu or 
 * http://www.evl.uic.edu/cavern/forum/
 *
*****************************************************************************************/


#ifndef _SAGECIRCBUF_H
#define _SAGECIRCBUF_H

#include "sageBase.h"

#ifdef BRIDGE_DEBUG_
	#define READER_OFFSET 1
#else
	#define READER_OFFSET 0
#endif

class readerInfo {
public:
	int readIdx;
	bool empty;
	
	readerInfo() : readIdx(0), empty(true) {}
};

class sageCircBuf {
private:
	int readIdx;
	int writeIdx;
	int noOfBlocks;	
	sageBlock *blockArray;	
	std::vector<readerInfo> readerList;
		
	pthread_mutex_t *bufLock;
	pthread_cond_t *notFull;
	pthread_cond_t *notEmpty;
	
	bool full, empty;
	int pixelBlockWidth, pixelBlockHeight;
    float bytesPerPixel;
		
public:
	sageCircBuf() : noOfBlocks(0), full(false), empty(true), 
		pixelBlockWidth(64), pixelBlockHeight(64), bytesPerPixel(3) {}
	int init(int blockNum);	
	
	sageBlock* getNextWriteBlock(); 	// Returns the next available sage block to write into
							// and advances the index. If no block is available, 
							// this function is blocked until a buffer is read and 
							// becomes available. 
	
	int updateReadIdx(int id);
	int updateReadIdx();
	int updateReadIdx(int id, int bufferMode);
	int updateWriteIdx();
	int distToWriteIdx(int ridx);

	sageBlock* readBlock();
	sageBlock* readBlock(int frameNum);
	sageBlock* readBlock(int id, bool blocking);
	void storeBlockConfig(sageBlock *block);

	int addReader();
	int removeReader(int readerID);
	~sageCircBuf();
};

#endif
